package crmdna.api.endpoint;

import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.google.appengine.api.users.User;

import crmdna.common.APIResponse;
import crmdna.common.APIResponse.Status;
import crmdna.common.RequestInfo;
import crmdna.common.Utils;
import crmdna.common.contact.ContactProp;
import crmdna.member.Member;
import crmdna.member.MemberLoader;
import crmdna.member.MemberProp;
import crmdna.member.MemberQueryCondition;

@Api(name = "member", description = "Member (alpha)", clientIds = {
		"220866004543.apps.googleusercontent.com",
		com.google.api.server.spi.Constant.API_EXPLORER_CLIENT_ID })
public class MemberApi {
	@ApiMethod(path = "create", httpMethod = HttpMethod.POST)
	public APIResponse create(@Nullable @Named("client") String client,
			@Named("groupId") long groupId,
			@Nullable @Named("email") String email,
			@Nullable @Named("firstName") String firstName,
			@Nullable @Named("lastName") String lastName,
			@Nullable @Named("mobilePhone") String mobilePhone,
			@Nullable @Named("homePhone") String homePhone,
			@Nullable @Named("officePhone") String officePhone,
			@Nullable @Named("homeAddress") String homeAddress,
			@Nullable @Named("officeAddress") String officeAddress,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			ContactProp contact = new ContactProp();
			contact.email = email;
			contact.firstName = firstName;
			contact.lastName = lastName;
			contact.mobilePhone = mobilePhone;
			contact.homePhone = homePhone;
			contact.officePhone = officePhone;
			contact.homeAddress.address = homeAddress;
			contact.officeAddress.address = officeAddress;

			login = Utils.getLoginEmail(user);
			MemberProp memberProp = Member.create(client, groupId, contact,
					false, login);

			return new APIResponse().status(Status.SUCCESS).object(memberProp);

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "updateContactDetails", httpMethod = HttpMethod.POST)
	public APIResponse updateContactDetails(
			@Nullable @Named("client") String client,
			@Named("memberId") long memberId,
			@Nullable @Named("email") String email,
			@Nullable @Named("firstName") String firstName,
			@Nullable @Named("lastName") String lastName,
			@Nullable @Named("mobilePhone") String mobilePhone,
			@Nullable @Named("homePhone") String homePhone,
			@Nullable @Named("officePhone") String officePhone,
			@Nullable @Named("homeAddress") String homeAddress,
			@Nullable @Named("homeCity") String homeCity,
			@Nullable @Named("homeState") String homeState,
			@Nullable @Named("homeCountry") String homeCountry,
			@Nullable @Named("homePincode") String homePincode,
			@Nullable @Named("officeAddress") String officeAddress,
			@Nullable @Named("officePincode") String officePincode,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			ContactProp contact = new ContactProp();
			contact.email = email;
			contact.firstName = firstName;
			contact.lastName = lastName;
			contact.mobilePhone = mobilePhone;
			contact.homePhone = homePhone;
			contact.officePhone = officePhone;
			contact.homeAddress.address = homeAddress;
			contact.homeAddress.city = homeCity;
			contact.homeAddress.state = homeState;
			contact.homeAddress.country = homeCountry;
			contact.homeAddress.pincode = homePincode;
			contact.officeAddress.address = officeAddress;
			contact.officeAddress.pincode = officePincode;

			login = Utils.getLoginEmail(user);
			MemberProp memberProp = Member.updateContactDetails(client,
					memberId, contact, login);

			return new APIResponse().status(Status.SUCCESS).object(memberProp);

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "get", httpMethod = HttpMethod.GET)
	public APIResponse get(@Nullable @Named("client") String client,
			@Named("memberId") long memberId,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			login = Utils.getLoginEmail(user);
			MemberProp memberProp = MemberLoader.safeGet(client, memberId,
					login).toProp();

			return new APIResponse().status(Status.SUCCESS).object(memberProp);

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "query", httpMethod = HttpMethod.GET)
	public APIResponse query(@Nullable @Named("client") String client,
			@Nullable @Named("searchStr") String searchStr,
			@Nullable @Named("groupIds") Set<Long> groupIds,
			@Nullable @Named("practiceIds") Set<Long> practiceIds,
			@Nullable @Named("programIds") Set<Long> programIds,
			@Nullable @Named("maxResultSize") Integer maxResultSize,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			if (maxResultSize == null)
				maxResultSize = 10;

			MemberQueryCondition qc = new MemberQueryCondition(client,
					maxResultSize).searchStr(searchStr).groupIds(groupIds)
					.practiceIds(practiceIds).programIds(programIds);

			login = Utils.getLoginEmail(user);
			List<MemberProp> memberProps = MemberLoader.querySortedProps(qc,
					login);

			return new APIResponse().status(Status.SUCCESS).object(memberProps)
					.message("No of records: " + memberProps.size());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "quickSearch", httpMethod = HttpMethod.GET)
	public APIResponse quickSearch(@Nullable @Named("client") String client,
			@Nullable @Named("searchStr") String searchStr,
			@Nullable @Named("groupIds") Set<Long> groupIds,
			@Nullable @Named("maxResultSizeDefault10") Integer maxResultSize,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			login = Utils.getLoginEmail(user);

			List<MemberProp> memberProps = MemberLoader.quickSearch(client,
					searchStr, groupIds, maxResultSize, login);

			return new APIResponse().status(Status.SUCCESS).object(memberProps)
					.message("No of records: " + memberProps.size());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "getDetailedInfo", httpMethod = HttpMethod.GET)
	public APIResponse getDetailedInfo(
			@Nullable @Named("client") String client,
			@Named("memberId") long memberId,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {

			login = Utils.getLoginEmail(user);
			MemberProp memberProp = MemberLoader.safeGetDetailedInfo(client,
					memberId, login);

			return new APIResponse().status(Status.SUCCESS).object(memberProp);

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "addOrDeleteProgram", httpMethod = HttpMethod.POST)
	public APIResponse addOrDeleteProgram(
			@Nullable @Named("client") String client,
			@Named("memberId") long memberId,
			@Named("programId") long programId, @Named("add") Boolean add,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			login = Utils.getLoginEmail(user);

			MemberProp memberProp = Member.addOrDeleteProgram(client, memberId,
					programId, add, login);

			return new APIResponse().status(Status.SUCCESS).object(memberProp);

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "addOrDeleteGroup", httpMethod = HttpMethod.POST)
	public APIResponse addOrDeleteGroup(@Named("client") String client,
			@Named("memberId") long memberId, @Named("groupId") long groupId,
			@Named("add") Boolean add,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (client == null)
			client = "isha";

		String login = null;

		try {
			login = Utils.getLoginEmail(user);

			MemberProp memberProp = Member.addOrDeleteGroup(client, memberId,
					groupId, add, login);

			return new APIResponse(Status.SUCCESS, memberProp);
		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}
}
